package main;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import filewatch.FileWatcher;
import filewatch.WatchDir;
import org.eclipse.jgit.api.AddCommand;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.api.errors.*;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;

/**
 *
 * @author thinner
 */
public class LapseCrate {

    public static final String WATCHED_DIRECTORIES_FILES = "dirs.ini";
    private WatchDir watcher;
    private FileWatcher debugWatcher = new FileWatcher() {

        @Override
        public void registered(Path path) {
            System.out.println("Registered " + path);
        }

        @Override
        public void unregistered(Path path) {
            System.out.println("Unregistered " + path);
        }

        @Override
        public void created(Path path) {
            System.out.println("Created " + path);
        }

        @Override
        public void deleted(Path path) {
            System.out.println("Deleted " + path);
        }

        @Override
        public void modified(Path path) {
            System.out.println("Modified " + path);
        }

        @Override
        public void overflow(Path path) {
            System.out.println("Overflow!!! WHAT TO DOOOO????? " + path);
        }

        @Override
        public void inaccessible(Path path) {
            System.out.println("Inaccessible, dunno why.. Or how... " + path);
        }

        @Override
        public void registerFailed(Path path, IOException exception) {
            System.out.println("Registering " + path + " failed: " + exception);
            exception.printStackTrace();
        }
    };

    private LapseCrate() throws IOException {
        this.watcher = new WatchDir();

//        // "Connect" to repo
//        File repoLoc = new File("~/Temp/gittest/lol2/.git").getAbsoluteFile();
//        FileRepositoryBuilder builder = new FileRepositoryBuilder();
//        Repository repo = builder.setGitDir(repoLoc).readEnvironment().build();
//
//        // Not really true... The file can exist but not be a repo
//        if (!repoLoc.exists()) {
//            System.out.println(repoLoc.getAbsolutePath() + " did not exist");
//            repo.create();
//        }
//
//        // Add something to the repo
//        Git git = new Git(repo);
//        // // Add files to the commit
//        AddCommand add = git.add();
//        add.addFilepattern("."); // Add everything in directory .
//        try {
//            add.call();
//            System.out.println("Added");
//        } catch (NoFilepatternException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (GitAPIException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        }
//
//        CommitCommand commit = git.commit();
//        try {
//            commit.setMessage("prutt").call();
//            System.out.println("Committed");
//        } catch (NoHeadException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (NoMessageException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (UnmergedPathsException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (ConcurrentRefUpdateException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (WrongRepositoryStateException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (GitAPIException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        }
//
//        PushCommand push = git.push();
//        try {
//            System.out.println("Pushing");
//            push.call();
//            System.out.println("Pushed");
//        } catch (InvalidRemoteException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (TransportException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (GitAPIException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        }
//
//        // Things should now be added... Lol..............
//        
//        
//        repo.close();
//        System.exit(0); 
    }

    private void dummyDirFile() throws IOException {
        FileWriter fw = new FileWriter(WATCHED_DIRECTORIES_FILES);
        fw.write(".\n");
        fw.close();
    }

    private void registerDirs() throws FileNotFoundException, IOException {
        Scanner scanner = new Scanner(new File(WATCHED_DIRECTORIES_FILES));
        while (scanner.hasNextLine()) {
            String[] parts = scanner.nextLine().split(";");
            String path = parts[0];
            boolean recursive = (parts.length > 1) ? Boolean.parseBoolean(parts[1]) : true;

            watcher.register(new File(path).toPath(), recursive);
        }
    }

    private void storeWatchedDirs() throws IOException {
        Collection<WatchDir.WatchContext> dirs = watcher.getWatchedPaths();
        FileWriter fw = new FileWriter(WATCHED_DIRECTORIES_FILES);
        for (WatchDir.WatchContext context : dirs) {
            StringBuilder sb = new StringBuilder();
            sb.append(context.getPath().toFile().getAbsolutePath());
            sb.append(";");
            sb.append(String.valueOf(context.isRecursive()));
            sb.append("\n");

            fw.write(sb.toString());
        }
        fw.close();
    }

    public static void main(String[] args) {
        try {
            LapseCrate lc = new LapseCrate();

            try {
                lc.registerDirs();
            } catch (FileNotFoundException ex) {
                System.out.println(WATCHED_DIRECTORIES_FILES + " not found, creating a dummy");
                try {
                    lc.dummyDirFile();
                    lc.registerDirs();
                } catch (IOException ex1) {
                    Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex1);
                    System.out.println("Aaaah... come on... Create it manually then...");
                    System.exit(1);
                }
            } catch (IOException ex) {
                Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
                System.exit(2);
            }

            lc.watcher.addFileWatcher(lc.debugWatcher);
            lc.watcher.start();

        } catch (IOException ex) {
            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
        }


//        CommandLineMethods cmd = new CommandLineMethods(Logger.getGlobal());
//
//        try {
//            Process ls = cmd.exec("ls");
//            System.out.println(cmd.readProcess(ls));
//        } catch (IOException ex) {
//            Logger.getLogger(LapseCrate.class.getName()).log(Level.SEVERE, null, ex);
//        }
    }
}
